const express = require("express");
const path = require("path");
const cookieParser = require("cookie-parser");
const logger = require("morgan");
const cors = require("cors");
const colorsRouter = require("./routes/colors");
const indexRouter = require("./routes/index");
const apiUsersRouter = require("./routes/api-users");
const adminUsersRouter = require("./routes/admin-users");
const booksRouter = require("./routes/books");
const session = require("express-session");
const { expressjwt: expressJWT } = require("express-jwt");
const mysql=require("mysql")
const secretKey='fanfan!!!'
const db=mysql.createPool({
  host:"localhost",
  user:"root",
  password:"123456",
  database:"nodejsdemo1"
})
const app = express();
// app.use:注册全局生效的中间件

// 手动添加CORS中间件，处理跨域请求
// app.use((req, res, next) => {
// 允许任何域的请求
//   res.header('Access-Control-Allow-Origin', '*');
//   // 允许所有 HTTP 方法
//   res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
//   // 允许所有请求头
//   res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');

//   next();
// });
// 配置 session 中间件
app.use(
  session({
    secret: "itheima", // 用于加密 session 数据的密钥
    resave: false, // 不重新保存 session 如果未修改
    saveUninitialized: true, // 保存未初始化的 session
  })
);
// 配置JWT验证中间件  只要配置好这个中间件，就可以在其他路由中使用req.user获取到当前登录用户的信息  这个是中间件自动挂载的
app.use(expressJWT({
  secret: secretKey,
  algorithms: ['HS256']
}).unless({
path: [/^\/api\//] // 所有以/api开头的接口都不需要验证
}));

// 使用 cors 中间件，处理跨域请求
app.use(cors());
// 使用 morgan 中间件，以 'dev' 格式记录请求日志，方便开发时查看请求信息
app.use(logger("dev"));
// 使用 express.json() 中间件，解析请求体中的 JSON 数据
app.use(express.json());
// 使用 express.urlencoded() 中间件，解析请求体中的表单数据，extended: false 表示使用查询字符串库解析
app.use(express.urlencoded({ extended: false }));
// 使用 cookie-parser 中间件，解析请求中的 cookie 数据
app.use(cookieParser());
// 托管静态资源
app.use("/public", express.static(path.join(__dirname, "public")));
// 前面的是访问前缀
app.use("/api", indexRouter);
app.use("/api/users", apiUsersRouter);
app.use("/api/colors", colorsRouter);
app.use("/api/books", booksRouter);
app.use("/admin/users", adminUsersRouter);
// 测试数据库连接
// db.query("select 1", (err, result) => { 
//   if (err) { 
//     return console.log(err.message)
//   }
//   console.log(result)
// })

// 查询users表中所有数据
db.query("select * from users", (err, result) => { 
  if (err) { 
    return console.log(err.message)
  }
  // select 查询出来的结果是数组
  console.log(result)
})
// // 插入数据
// const user={
//   id: '0003',
//   name: '张三',
//   age: 18,
// }
// // ???是占位符
// const sqlStr1="insert into users (id,name,age) values (?,?,?)"
// db.query(sqlStr1,[user.id,user.name,user.age],(err,result)=>{
//   if (err) { 
//     return console.log(err.message)
//   }
// insert into 出来的是一个对象
//   console.log(result)
// })


// 当数据对象的每个属性和数据表的字段名一致时，才能使用这种方式插入数据  简便操作
// const user2 = {
//   id: '0004',
//   name: '田先金',
//   age: 20
// }
// // 插入数据
// const sqlStr2 = "insert into users set ?"
// db.query(sqlStr2,user2,(err,result)=>{
//   if (err) { 
//     return console.log(err.message)
//   }
//   console.log(result)
// })

// // 更新数据
// const user3 = {
//   id: '0003',
//   name: '林超威',
//   age: 20
// }
// // 也是可以便捷设置
// const sqlStr3="update users set ? where id=?"
// db.query(sqlStr3,[user3,user3.id],(err,result)=>{
//   if (err) { 
//     return console.log(err.message)
//   }
//   // 也是返回一个对象
//   console.log(result)
// })

// 删除id为'0004'的用户
// const sqlStr4="delete from users where id=?"
// db.query(sqlStr4, '0004', (err, result) => { 
//   if (err) { 
//     return console.log(err.message)
//   }
//   // 也是返回一个对象
//   console.log(result)
// })

// // 假删除 更新status为-1为删除 0为正常
// const sqlStr4="update users set del_status=1 where id=?"
// db.query(sqlStr4, '0001', (err, result) => { 
//   if (err) { 
//     return console.log(err.message)
//   }
//   // 也是返回一个对象
//   console.log(result)
// })



// 404 处理中间件
app.use((req, res, next) => {
  res.status(404).json({
    data: {
      message: "资源不存在",
    },
  });
});
//登录过期 错误处理中间件
app.use((err, req, res, next) => { 
  if (err.name === "UnauthorizedError") { 
    return res.send({
      status: 401,
      data: {
        message: "登录过期，请重新登录",
      },
    })
  }
  res.send({
    status: 500,
    data: {
      message: "服务器内部错误",
    },
  })
})

// 错误处理中间件 - 必须放在所有路由之后
app.use((err, req, res, next) => {
  console.error("错误详情:", err.message);
  // 判断错误类型
  if (err.message === "not found") {
    res.status(404).json({
      data: {
        message: "资源不存在",
        error: err.message,
      },
    });
  } else {
    // 其他类型的错误
    res.status(500).json({
      data: {
        message: "服务器内部错误",
        error: err.message,
      },
    });
  }
});

module.exports = app;
